/**
 * 
 */
package lt.vin.exaatto.shared;

import java.util.HashSet;
import java.util.Set;

import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * @author Vincentas
 *
 */
@PersistenceCapable(detachable="true")
public class Chat implements IsSerializable {

	public static final String SUFIX = "@exa-atto.appspotchat.com";
	/**
	 * 
	 */
	private static final long serialVersionUID = 4538734920909129226L;

	@PrimaryKey
	private String id;
	
	@Persistent
	private String name;
	
	@Persistent
	private String owner; 
	
	@Persistent
	private Set<String> managers = new HashSet<String>();
	
	@Persistent
	private Set<String> members = new HashSet<String>();

	@Persistent
	private Set<String> allMembers = new HashSet<String>();
	
	public Chat() {
		
	}
	
	public Chat(String id, String owner) {
		setId(id);
		setOwner(owner);
		setName(id);
	}
	
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	public void addMember(String user) {
		if (user.equalsIgnoreCase(id + SUFIX)) {
			throw new Error("Cant add chat to self");
		}

		if (isManager(user)) {
			throw new Error("User already is manager");
		}
		
		getMembers().add(user.toLowerCase());
		allMembers.add(user.toLowerCase());
	}
	
	public void removeMember(String user) {
		getMembers().remove(user.toLowerCase());
		
		if (members.isEmpty()) {
			members = null;
		}
		
		allMembers.remove(user.toLowerCase());
	}
	
	public Set<String> getMembers() {
		if (members == null) {
			members = new HashSet<String>();
		}
		
		return members;
		
	}
	
	public boolean isMember(String user) {
		return getAllMembers().contains(user.toLowerCase());
	}
	
	public void addManager(String user) {
		if (user.equalsIgnoreCase(id + SUFIX)) {
			throw new Error("Cant add chat to self");
		}

		if (isMember(user)) {
			throw new Error("User is already member");
		}
		
		getManagers().add(user.toLowerCase());
		allMembers.add(user.toLowerCase());
	}
	
	public void removeManager(String user) {
		getManagers().remove(user.toLowerCase());
		
		if (managers.isEmpty()) {
			managers = null;
		}
		allMembers.remove(user.toLowerCase());
	}
	
	public Set<String> getManagers() {
		if (managers ==  null) {
			managers = new HashSet<String>();
		}
		
		return managers;
	}
	
	public boolean isManager(String user) {
		return getManagers().contains(user.toLowerCase()) || owner.equalsIgnoreCase(user);
	}

	/**
	 * @return the owner
	 */
	public String getOwner() {
		return owner;
	}

	/**
	 * @param user the owner to set
	 */
	public void setOwner(String user) {
		if (user.equalsIgnoreCase(id + SUFIX)) {
			throw new Error("Cant add chat to self");
		}
		
		if (this.owner != null) {
			if (this.owner.equalsIgnoreCase(user)) {
				return;
			}
			
			addManager(this.owner);
		}
		
		this.owner = user.toLowerCase();
		allMembers.add(user.toLowerCase());
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return getId().hashCode();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Chat) {
			Chat chat = (Chat) obj;
			return chat.getId().equals(getId());
		}
		
		return false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return getName();
	}

	/**
	 * @return the allMembers
	 */
	public Set<String> getAllMembers() {
		return allMembers;
	}		
}
